class Logger {
  /**
   * 构造函数：初始化日志配置
   * @param {Object} options - 配置选项
   * @param {boolean} options.enableRemoteLog - 是否启用远程日志
   * @param {object} options.remoteLogger - 远程日志实例（如 wx.getRealtimeLogManager()）
   */
  constructor({ enableRemoteLog = false, remoteLogger = null } = {}) {
    if (Logger.instance) {
      return Logger.instance; // 如果实例已存在，直接返回
    }

    this.enableRemoteLog = enableRemoteLog; // 是否启用远程日志
    this.remoteLogger = remoteLogger; // 远程日志实例

    Logger.instance = this; // 保存实例
  }

  /**
   * 获取当前时间戳
   * @returns {string} 格式化的时间戳 (YYYY-MM-DD HH:mm:ss)
   */
  getTimestamp() {
    const now = new Date();
    const year = now.getFullYear();
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const day = String(now.getDate()).padStart(2, '0');
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  /**
   * 获取调用日志的代码位置
   * @returns {string} 调用日志的代码位置，例如 "index.js:15:10"
   */
  getCallerInfo() {
    try {
      const error = new Error();
      const stackLines = error.stack.split('\n');
      // 通常第 4 行是调用日志的代码位置（第 3 行是 log 方法内部）
      const callerLine = stackLines[4] || '';
      const match = callerLine.match(/at (.+) \((.+):(\d+):(\d+)\)/) || callerLine.match(/at (.+):(\d+):(\d+)/);

      if (match) {
        const fileName = match[2] || ''; // 文件路径
        const lineNumber = match[3] || ''; // 行号
        const columnNumber = match[4] || ''; // 列号
        return `${fileName}:${lineNumber}:${columnNumber}`;
      }
      return 'unknown location';
    } catch (err) {
      return 'unknown location';
    }
  }

  /**
   * 通用日志方法
   * @param {string} level - 日志级别：'info' | 'warn' | 'error'
   * @param {string} message - 日志信息
   * @param {object} data - 附加数据
   */
  log(level, message, data = {}) {
    const timestamp = this.getTimestamp(); // 获取当前时间戳
    const callerInfo = this.getCallerInfo(); // 获取调用代码位置

    // 构造日志内容
    const logEntry = {
      logLevel: level,
      timestamp: timestamp,
      message: message || '',
      data: data || {},
      location: callerInfo // 调用代码的位置
    };

    // 打印日志到控制台
    console.log(JSON.stringify(logEntry, null, 2));

    // 如果启用了远程日志，记录到远程
    if (this.enableRemoteLog && this.remoteLogger) {
      try {
        if (level === 'info') {
          this.remoteLogger.info(logEntry);
        } else if (level === 'warn') {
          this.remoteLogger.warn(logEntry);
        } else if (level === 'error') {
          this.remoteLogger.error(logEntry);
        }
      } catch (err) {
        console.error('远程日志记录失败：', err);
      }
    }
  }

  /**
   * 记录 info 日志
   * @param {string} message - 日志信息
   * @param {object} data - 附加数据
   */
  info(message, data = {}) {
    this.log('info', message, data);
  }

  /**
   * 记录 warn 日志
   * @param {string} message - 日志信息
   * @param {object} data - 附加数据
   */
  warn(message, data = {}) {
    this.log('warn', message, data);
  }

  /**
   * 记录 error 日志
   * @param {string} message - 日志信息
   * @param {object} data - 附加数据
   */
  error(message, data = {}) {
    this.log('error', message, data);
  }

  // 静态方法：初始化 Logger 单例
  static init({ enableRemoteLog = false, remoteLogger = null } = {}) {
    if (!Logger.instance) {
      Logger.instance = new Logger({ enableRemoteLog, remoteLogger });
    }
  }

  // 静态方法：记录 info 日志
  static info(message, data = {}) {
    if (!Logger.instance) {
      throw new Error('Logger is not initialized. Call Logger.init() first.');
    }
    Logger.instance.info(message, data);
  }

  // 静态方法：记录 warn 日志
  static warn(message, data = {}) {
    if (!Logger.instance) {
      throw new Error('Logger is not initialized. Call Logger.init() first.');
    }
    Logger.instance.warn(message, data);
  }

  // 静态方法：记录 error 日志
  static error(message, data = {}) {
    if (!Logger.instance) {
      throw new Error('Logger is not initialized. Call Logger.init() first.');
    }
    Logger.instance.error(message, data);
  }
}

module.exports = Logger;